package com.yzy.fly.config.properties;

import com.yzy.fly.api.function.security.FlyApiSecurity;
import com.yzy.fly.api.function.security.FlyDefaultApiSecurity;
import com.yzy.fly.exception.ApiSecurityException;
import com.yzy.fly.function.logging.Log;
import com.yzy.fly.function.logging.LogFactory;
import com.yzy.fly.util.ClassUtil;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Constructor;

@ConfigurationProperties(
        prefix = "rsa.encrypt"
)
@Configuration
//@DependsOn("flyConfig")
public class SecretKeyConfig {

    private static Log log = LogFactory.getLog(SecretKeyConfig.class);

    private String privateKey;
    private String publicKey;
    private String charset = "UTF-8";
    private boolean open = true;
    private boolean showLog = false;

    private String securityImpl;
    protected Class<? extends FlyApiSecurity> securityImplClass;
    private static Constructor<? extends FlyApiSecurity> securityConstructor;

    static{
        tryImplementation(SecretKeyConfig::userFlyDefaultApiSecurity);
    }

    private static void tryImplementation(Runnable runnable) {
        if (securityConstructor == null) {
            try {
                runnable.run();
            } catch (Throwable t) {
                // ignore
            }
        }
    }

    public SecretKeyConfig() {
    }

    public static synchronized void userFlyDefaultApiSecurity(){
        setImplementation(FlyDefaultApiSecurity.class);
    }

    public String getPrivateKey() {
        return this.privateKey;
    }

    public void setPrivateKey(String privateKey) {
        this.privateKey = privateKey;
    }

    public String getPublicKey() {
        return this.publicKey;
    }

    public void setPublicKey(String publicKey) {
        this.publicKey = publicKey;
    }

    public String getCharset() {
        return this.charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public boolean isOpen() {
        return this.open;
    }

    public void setOpen(boolean open) {
        this.open = open;
    }

    public boolean isShowLog() {
        return this.showLog;
    }

    public void setShowLog(boolean showLog) {
        this.showLog = showLog;
    }

    public String getSecurityImpl() {
        return this.securityImpl;
    }

    public void setSecurityImpl(final String securityImpl) {
        Class<? extends FlyApiSecurity> securityImplClass = ClassUtil.resolveClass(securityImpl,false);
        if (securityImpl != null) {
            this.securityImpl = securityImpl;
            this.securityImplClass = securityImplClass;
            setImplementation(securityImplClass);
        }
    }

    private static void setImplementation(Class<? extends FlyApiSecurity> implClass) {
        try {
            Constructor<? extends FlyApiSecurity> candidate = implClass.getConstructor();
//            FlyApiSecurity flyApiSecurity = candidate.newInstance();
            if (log.isDebugEnabled()) {
                log.debug("ApiSecurity initialized using '" + implClass + "' adapter.");
            }
            securityConstructor = candidate;
        } catch (Throwable t) {
            throw new ApiSecurityException(303,"Error setting FlyApiSecurity implementation.Cause: " + t);
        }
    }

    public Constructor<? extends FlyApiSecurity> getSecurityConstructor() {
        return securityConstructor;
    }
}
